package com.java.project.controller.api;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.java.common.utils.tool.Md5Utils;
import com.java.common.utils.tool.StringUtils;
import com.java.framework.web.controller.BaseController;
import com.java.framework.web.domain.AjaxResult;
import com.java.project.project.activity.domain.ActivityProduct;
import com.java.project.project.activity.service.IActivityProductService;
import com.java.project.project.fulu.domain.Card;
import com.java.project.project.fulu.domain.Order;
import com.java.project.project.fulu.service.ICardService;
import com.java.project.project.fulu.service.IOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;

@Api(tags = {"活动商品API"})
@RestController
@RequestMapping("/api/activityApi")
public class ActivityApiController extends BaseController {

    @Resource
    private IActivityProductService activityProductService;
    @Value("${fulu.app_key}")
    public String appKey;
    @Value("${fulu.app_secret}")
    public String appSecret;
    @Value("${fulu.url}")
    public String url;
    @Resource
    private IOrderService orderService;
    @Resource
    private ICardService cardService;

    Format format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Format format1 = new SimpleDateFormat("yyyyMMddHHmmss");

    @ApiOperation("获取活动商品列表")
    @GetMapping("getActivityGoodsList")
    public AjaxResult getActivityGoodsList() {
        List<ActivityProduct> activityProducts = activityProductService.selectActivityProductList(new ActivityProduct());
        return AjaxResult.success(activityProducts);
    }

    @ApiOperation("直充下单接口")
    @PostMapping("orderDirect")
    public AjaxResult orderDirect(@ApiParam(value = "活动商品ID", required = true) @RequestParam(value = "id", required = true) String activityProductId,
                                  @ApiParam(value = "充值账号", required = true) @RequestParam(value = "chargeAccount", required = true) String chargeAccount,
                                  @ApiParam(value = "购买数量", required = true) @RequestParam(value = "buyNum", required = true) Long buyNum) throws InterruptedException {
        ActivityProduct activityProduct = activityProductService.selectActivityProductById(activityProductId);
        if (activityProduct==null){
            return AjaxResult.error("活动商品ID不存在!");
        }
        JSONObject req = new JSONObject();
        Random rand = new Random();
        req.put("app_key",appKey);
        req.put("method","fulu.order.direct.add");
        req.put("timestamp",format.format(new Date()));
        req.put("version","2.0");
        req.put("format","json");
        req.put("charset","utf-8");
        req.put("sign_type","md5");
        req.put("app_auth_token","");
        JSONObject biz_content = new JSONObject();
        biz_content.put("product_id",Long.valueOf(activityProduct.getProductId()));
        String customerOrderNo = format1.format(new Date()) + toFixdLengthString((rand.nextInt(9999) + 1),4);
        biz_content.put("customer_order_no",customerOrderNo);
        biz_content.put("charge_account",chargeAccount);
        biz_content.put("buy_num",buyNum);
        req.put("biz_content",biz_content.toJSONString());
        String sign = Sign(appSecret,req);
        req.put("sign",sign);
        System.out.println("request:"+req.toJSONString());
        String respon = HttpUtil.post(url, req.toJSONString());
        System.out.println("respon:"+respon);
        JSONObject result = JSONObject.parseObject(respon);
        if (Integer.parseInt(result.get("code").toString())==0){
            //接口调用成功
            //轮询调订单查询接口
            JSONObject orderJson;
            Order order = new Order();
            long start = System.currentTimeMillis();
            do {
                Thread.sleep(3 * 1000);
                orderJson = getOrderStatus(customerOrderNo);
                if (orderJson.getInteger("code")==0){
                    order = orderJson.getJSONObject("result").toJavaObject(Order.class);
                    order.setActivityProductId(activityProductId);
                }
            } while ((StringUtils.equals(order.getOrderState(),"processing")||StringUtils.equals(order.getOrderState(),"untreated")) && (System.currentTimeMillis()-start) < 10 * 1000);
            if (order!=null){
                switch (order.getOrderState()){
                    case "success":
                        orderService.insertOrder(order);
                        return AjaxResult.success("直充成功!");
                    case "failed":
                        orderService.insertOrder(order);
                        return AjaxResult.error("直充失败!");
//                    case 4:
//                        return AjaxResult.error("未处理!");
                    default:
                        orderService.insertOrder(order);
                        return AjaxResult.error("处理中!");
                }
            }else {
                //接口调用失败
                return AjaxResult.error("接口调用失败"+orderJson.getString("message"));
            }
        }else {
            //接口调用失败
            return AjaxResult.error("接口调用失败,"+result.getString("message"));
        }
    }

    @ApiOperation("卡密下单接口")
    @PostMapping("orderCard")
    public AjaxResult orderCard(@ApiParam(value = "活动商品ID", required = true) @RequestParam(value = "id", required = true) String activityProductId,
                                  @ApiParam(value = "购买数量", required = true) @RequestParam(value = "buyNum", required = true) Long buyNum) throws InterruptedException {
        ActivityProduct activityProduct = activityProductService.selectActivityProductById(activityProductId);
        if (activityProduct==null){
            return AjaxResult.error("活动商品ID不存在!");
        }
        JSONObject req = new JSONObject();
        Random rand = new Random();
        req.put("app_key",appKey);
        req.put("method","fulu.order.card.add");
        req.put("timestamp",format.format(new Date()));
        req.put("version","2.0");
        req.put("format","json");
        req.put("charset","utf-8");
        req.put("sign_type","md5");
        req.put("app_auth_token","");
        JSONObject biz_content = new JSONObject();
        biz_content.put("product_id",Long.valueOf(activityProduct.getProductId()));
        String customerOrderNo = format1.format(new Date()) + toFixdLengthString((rand.nextInt(9999) + 1),4);
        biz_content.put("customer_order_no",customerOrderNo);
        biz_content.put("buy_num",buyNum);
        req.put("biz_content",biz_content.toJSONString());
        String sign = Sign(appSecret,req);
        req.put("sign",sign);
        System.out.println("request:"+req.toJSONString());
        String respon = HttpUtil.post(url, req.toJSONString());
        System.out.println("respon:"+respon);
        JSONObject result = JSONObject.parseObject(respon);
        if (Integer.parseInt(result.get("code").toString())==0){
            //接口调用成功
            //轮询调订单查询接口
            JSONObject orderJson;
            Order order = new Order();
            long start = System.currentTimeMillis();
            do {
                Thread.sleep(3 * 1000);
                orderJson = getOrderStatus(customerOrderNo);
                if (orderJson.getInteger("code")==0){
                    order = orderJson.getJSONObject("result").toJavaObject(Order.class);
                    order.setActivityProductId(activityProductId);
                }
            } while ((StringUtils.equals(order.getOrderState(),"processing")||StringUtils.equals(order.getOrderState(),"untreated")) && (System.currentTimeMillis()-start) < 10 * 1000);
            if (order!=null){
                switch (order.getOrderState()){
                    case "success":
                        String id = orderService.insertOrder(order);
                        List<Card> cards = order.getCards();
                        StringBuilder cardStr = new StringBuilder();
                        if (StringUtils.isNotEmpty(cards)){
                            cards.forEach(card -> {
                                card.setOrderId(id);
                                cardService.insertCard(card);
                                cardStr.append("卡号:"+card.getCardNumber()+",卡密:"+card.getCardPwd());
                            });
                        }
                        return AjaxResult.success("卡密下单成功!"+cardStr);
                    case "failed":
                        orderService.insertOrder(order);
                        return AjaxResult.error("卡密下单失败!");
//                    case 4:
//                        return AjaxResult.error("未处理!");
                    default:
                        orderService.insertOrder(order);
                        return AjaxResult.error("处理中!");
                }
            }else {
                //接口调用失败
                return AjaxResult.error("接口调用失败"+orderJson.getString("message"));
            }
        }else {
            //接口调用失败
            return AjaxResult.error("接口调用失败,"+result.getString("message"));
        }
    }

    //签名计算
    public String Sign(String sysSecret,JSONObject map){

        char[] s = JSONObject.toJSONString(map, SerializerFeature.WriteMapNullValue).toCharArray();
        Arrays.sort(s);

        String outputSignOriginalStr = new String(s) + sysSecret;
        String sign = Md5Utils.MD5(outputSignOriginalStr);
        return sign;
    }


    public String toFixdLengthString(long num, int fixdlenth) {
        StringBuffer sb = new StringBuffer();
        String strNum = String.valueOf(num);
        if (fixdlenth - strNum.length() >= 0) {
            sb.append(generateZeroString(fixdlenth - strNum.length()));
        } else {
            throw new RuntimeException("将数字" + num + "转化为长度为" + fixdlenth
                    + "的字符串发生异常！");
        }
        sb.append(strNum);
        return sb.toString();
    }

    public String generateZeroString(int length) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            sb.append('0');
        }
        return sb.toString();
    }

    /**
     * 返回(0-接口调用失败,1-成功,2-处理中,3-失败,4-未处理)
     * @param customerOrderNo
     * @return
     */
    public JSONObject getOrderStatus(String customerOrderNo){
        JSONObject req = new JSONObject();
        req.put("app_key",appKey);
        req.put("method","fulu.order.info.get");
        req.put("timestamp",format.format(new Date()));
        req.put("version","2.0");
        req.put("format","json");
        req.put("charset","utf-8");
        req.put("sign_type","md5");
        req.put("app_auth_token","");
        JSONObject biz_content = new JSONObject();
        biz_content.put("customer_order_no",customerOrderNo);
        req.put("biz_content",biz_content.toJSONString());
        String sign = Sign(appSecret,req);
        req.put("sign",sign);
        System.out.println("request:"+req.toJSONString());
        String respon = HttpUtil.post(url, req.toJSONString());
        System.out.println("respon:"+respon);
        JSONObject result = JSONObject.parseObject(respon);
        return result;
//        if (Integer.parseInt(result.get("code").toString())==0){
//            //接口调用成功
//            Order order = result.getJSONObject("result").toJavaObject(Order.class);
//            if (StringUtils.equals(order.getOrderState(),"success")){
//                //直充成功
//                return 1;
//            }else if (StringUtils.equals(order.getOrderState(),"untreated")){
//                //未处理
//                return 4;
//            }else if (StringUtils.equals(order.getOrderState(),"failed")){
//                //失败
//                return 3;
//            }else {
//                //处理中,轮询调订单查询接口
//                return 2;
//            }
//            return order;
//        }else {
//            //接口调用失败
//            return null;
//        }
    }
}
